﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Microsoft.Office.Interop.Excel;
using Tp.Base;
using Tp.GUI.Dialog;
using Tp.Interface;
using Tp.Properties;
using TpBaseObjects.Base;
using TpLogger;
using TpTools;
using myWord = Microsoft.Office.Interop.Word;
using TpExtensions;

namespace Tp {

    [ClassInterface(ClassInterfaceType.None)]
    [Guid("13FE32AD-4BF8-495f-AB4D-6C61BD463EA4")]

    [ProgId("TP.ExcelWork")]
    public class ExcelWork : AbstractExcelTools, IExcelInterface {

        #region Members

        private Logger log;
        private struct FC {

            #region Menüeinträge

            // Neues Arbeitsblatt
            public static int Angebot = 1;
            public static int Abrechnung = 16;
            public static int Abnahmeprotokoll = 2;
            public static int Auftragsbestaetigung = 14;
            public static int Lieferschein = 3;
            public static int Projektbericht = 4;
            public static int Projekt = 5;
            public static int Rechnug = 15;

            //Export + Funktion
            public static int Aepü = 6;
            public static int LeistungenProjekt = 7;
            public static int Leistungen = 8;

            //Export + Funktion + Dokument
            public static int DokumentAngebot = 9;
            public static int DokumentAuftragsbestätigung = 10;
            public static int DokumentRechnung = 11;

            //Import Ka
            //public static int ImportKa = 12; //Reserve da nicht realisiert wird.

            //Bearbeitung Ka
            //public static int BearbeiteKa = 13; //Reserve da nicht realisiert wird.

            //Export Intern
            public static int ExportJobevidenzIntern = 17;
            public static int ExportLeistungenIntern = 18;

            //Funktion
            public static int AuswahlKA = 12;

            #endregion

            #region Sonstige Events

            //21 ...
            public static int CheckWorkSheets = 21;
            public static int SetRightMouseMenu = 22;

            public static int WBActivate = 25;
            public static int WBAfterSave = 26;
            public static int WBBeforeClose = 27;
            public static int WBBeforeSave = 28;
            public static int WBDeactivate = 29;
            public static int WBOpen = 30;
            public static int WBSheetActivate = 31;
            public static int WBSheetCalculate = 32;
            public static int WBSheetChange = 33;
            public static int WBSheetSelectionChange = 34;
            public static int WBBeforePrint = 35;
            public static int WBSheetDeactivate = 36;
            public static int WBAddinInstall = 37;
            public static int WBAddinUninstall = 38;
            public static int WBAfterXmlExport = 39;
            public static int WBAfterXmlImport = 40;
            public static int WBBeforeXmlExport = 41;
            public static int WBBeforeXmlImport = 42;
            public static int WBNewChart = 43;
            public static int WBNewSheet = 44;
            public static int WBSheetBeforeDoubleClick = 45;
            public static int WBSheetBeforeRightClick = 46;
            public static int WBSheetFollowHyperlink = 47;
            public static int WBWindowActivate = 48;
            public static int WBWindowDeactivate = 49;
            public static int WBWindowResize = 50;

            public static int WSActivate = 51;
            public static int WSBeforeDoubleClick = 52;
            public static int WBBeforeRightClick = 53;
            public static int WSCalculate = 54;
            public static int WSChange = 55;
            public static int WSDeactivate = 56;
            public static int WSFollowHyperlink = 57;
            public static int WSSelectionChange = 58;

            public static int TestRoutine = 99;

            #endregion

            #region WordCore

            public static int wordSendThisDocument = 31;

            #endregion

        }

        #endregion

        #region Constructor

        public ExcelWork() {
            log = new Logger();
            Settings.Default.Reload();
            log.Add("Start ExcelWork (" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() + ")");
            Core.AddMenuEntries(log);
        }

        #endregion

        #region Overrides

        public override void SetTpUser() {
            throw new NotImplementedException();
        }

        #endregion

        #region Properties


        #endregion

        #region Methods

        public void ExcelCore(Microsoft.Office.Interop.Excel.Application exApp, Workbook wb, Worksheet sh, int CoreFunctionNumber) {
            ExcelCore(exApp, wb, sh, CoreFunctionNumber, null);
        }

        public void ExcelCore(Microsoft.Office.Interop.Excel.Application exApp, Workbook wb, Worksheet sh, int CoreFunctionNumber, Range r1) {

            #region ExcelSettings

            SetApplication(exApp, false);


            #endregion

            try {

                #region Members

                ProjectSheet mySheet = new ProjectSheet(sh);


                #endregion

                #region ContextMenüeinträge

                #region Neues Arbeitsblatt

                #region Abnahmeprotokoll

                if (CoreFunctionNumber == FC.Abnahmeprotokoll) {
                    Reparatur rep;
                    if (mySheet.CalcType == "R") {
                        rep = new Reparatur(2);
                    } else {
                        rep = new Reparatur();
                    }

                    rep.ShowDialog();
                    if (!rep.Cancel) {
                        string sheetVorlage = Settings.Default.VorlageExcelAbnahmeprotokollProjekt;
                        if (rep.IsReparatur) {
                            sheetVorlage = Settings.Default.VorlageExcelAbnahmeprotokollReparatur;
                        }
                        string sAfter = Core.GetAfterSheetName(exApp, mySheet.ProjektNummer, Core.SheetType.Abnahmeprotokoll, wb, log);
                        string newSheetName = Core.GetSheetName(Core.SheetType.Abnahmeprotokoll, mySheet.ProjektNummer, wb, sh);
                        Worksheet afterSheet = wb.Sheets[sAfter];
                        Worksheet ap = wb.Sheets.Add(After: afterSheet, Type: sheetVorlage);
                        ap.Name = newSheetName;
                        log.Abort = false;
                        Core.Abnahmeprotokoll(wb, sh, ap, rep.IsReparatur, log);
                        if (log.Abort) {
                            ((Worksheet)wb.Sheets[ap.Name]).Delete();
                            return;
                        }
                        ap.CustomProperties.Add("SheetType", Core.SheetType.Abnahmeprotokoll);
                        ap.Activate();
                    }
                }

                #endregion

                #region Abrechnung

                if (CoreFunctionNumber == FC.Abrechnung) {
                    ProjectSheet sheet = new ProjectSheet(sh);
                    if (!sheet.IsCalcSheet) {
                        return;
                    }
                    if (sheet.CalcType != "KA") {
                        MessageBox.Show(Resources.NurAusKa, sh.Name, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        return;
                    }

                    string sAfter = Core.GetAfterSheetName(exApp, mySheet.ProjektNummer, Core.SheetType.Abrechnung, wb, log);
                    string newSheetName = Core.GetSheetName(Core.SheetType.Abrechnung, mySheet.ProjektNummer, wb, sh);
                    if (Tools.SheetsExists(wb, newSheetName)) {
                        string msg = "Das Arbeitsblatt '" + newSheetName + "' ist bereits vorhanden! Eine Änderung kann nur aus PXr erfolgen.";
                        MessageBox.Show(msg, wb.Name.ToString(), MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        return;
                    }
                    Worksheet afterSheet = wb.Sheets[sAfter];
                    Worksheet abrechnung = null;
                    int indexSheet = wb.Sheets.Count;
                    sh.Copy(After: afterSheet);
                    int activeIndex = ((Worksheet)wb.ActiveSheet).Index;
                    abrechnung = wb.Sheets[activeIndex];
                    abrechnung.Name = newSheetName;
                    Core.Abrechnung(exApp, wb, abrechnung, log);
                    ProjectSheet arSheet = new ProjectSheet(abrechnung);
                    arSheet.HiddenConditionRows(log);
                    arSheet.HiddenSonderConditionRows(log);
                    abrechnung.CustomProperties.Add("SheetType", Core.SheetType.Abrechnung);
                    abrechnung.Activate();
                }

                #endregion

                #region Angebot

                if (CoreFunctionNumber == FC.Angebot) {
                    ProjectSheet sheet = new ProjectSheet(sh);
                    string sAfter = Core.GetAfterSheetName(exApp, mySheet.ProjektNummer, Core.SheetType.Angebot, wb, log);
                    string newSheetName = Core.GetSheetName(Core.SheetType.Angebot, mySheet.ProjektNummer, wb, sh);
                    if (Tools.SheetsExists(wb, newSheetName)) {
                        string msg = "Das Arbeitsblatt '" + newSheetName + "' ist bereits vorhanden!\r\n\r\n" + "Soll das bestehende Arbeitsblatt gelöscht werden?";
                        if (MessageBox.Show(msg, wb.Name.ToString(), MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes) {
                            ((Worksheet)wb.Sheets[newSheetName]).Delete();
                            sAfter = Core.GetAfterSheetName(exApp, mySheet.ProjektNummer, Core.SheetType.Angebot, wb, log);
                        } else {
                            sAfter = newSheetName;
                            newSheetName += "(" + ((int)Core.CountSameSheets(wb, newSheetName) + 1).ToString() + ")";
                        }
                    }
                    Worksheet afterSheet = wb.Sheets[sAfter];
                    Worksheet angebot = wb.Sheets.Add(After: afterSheet, Type: Settings.Default.VorlageExcelAngebot);
                    angebot.Name = newSheetName;
                    Core.AngebotNeu(exApp, wb, sh, angebot, log);
                    angebot.CustomProperties.Add("SheetType", Core.SheetType.Angebot);
                    angebot.Activate();
                }

                #endregion

                #region Auswahl KA

                if (CoreFunctionNumber == FC.AuswahlKA) {
                    Core.CreateNewCalc(sh, log);
                }

                #endregion

                #region Auftragsbestaetigung

                if (CoreFunctionNumber == FC.Auftragsbestaetigung) {
                    ProjectSheet sheet = new ProjectSheet(sh);
                    string sAfter = Core.GetAfterSheetName(exApp, mySheet.ProjektNummer, Core.SheetType.Auftragsbestaetigung, wb, log);
                    string newSheetName = Core.GetSheetName(Core.SheetType.Auftragsbestaetigung, mySheet.ProjektNummer, wb, sh);
                    if (sheet.CalcType == "K") {
                        string msg = "Eine Auftragsbestaetigung ist vom Arbeitsplatz PXka möglich.";
                        MessageBox.Show(msg, wb.Name.ToString(), MessageBoxButtons.OK);
                        return;
                    }
                    if (sheet.CalcType != "R") {
                        if (Tools.SheetsExists(wb, newSheetName)) {
                            string msg = "Das Arbeitsblatt '" + newSheetName + "' ist bereits vorhanden!\r\n\r\n" + "Eine Änderung ist nur vom Arbeitsblatt PXr möglich.";
                            MessageBox.Show(msg, wb.Name.ToString(), MessageBoxButtons.OK);
                            return;
                        }
                    } else {
                        if (Tools.SheetsExists(wb, newSheetName)) {
                            //string msg = "Das Arbeitsblatt '" + newSheetName + "' ist bereits vorhanden!\r\n\r\n" + "Soll das bestehende Arbeitsblatt gelöscht werden?";
                            //if (MessageBox.Show(msg, wb.Name.ToString(), MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes) {
                            //    ((Worksheet)wb.Sheets[newSheetName]).Delete();
                            //    sAfter = Core.GetAfterSheetName(exApp, mySheet.ProjektNummer, Core.SheetType.Auftragsbestaetigung, wb, log);
                            //} else {
                            bool weiter = false;
                            while (weiter == false) {
                                sAfter = newSheetName;
                                newSheetName = Tools.Left(sAfter, sAfter.Length - 1) + Core.GetNextSheetCharacter("a", wb, false);
                                if (!Tools.SheetsExists(wb, newSheetName)) {
                                    char myCharacter = Convert.ToChar(newSheetName.Right(1));
                                    int myChar = myCharacter;
                                    myChar--;
                                    sAfter = Tools.Left(sAfter, sAfter.Length - 1) + ((char)myChar).ToString();
                                    weiter = true;
                                }
                            }
                            //}

                        }
                    }
                    Worksheet afterSheet = wb.Sheets[sAfter];
                    Worksheet auftrag = wb.Sheets.Add(After: afterSheet, Type: Settings.Default.VorlageExcelAngebot);
                    auftrag.Name = newSheetName;
                    Core.AngebotNeu(exApp, wb, sh, auftrag, log);
                    auftrag.CustomProperties.Add("SheetType", Core.SheetType.Auftragsbestaetigung);
                    auftrag.Activate();
                }

                #endregion

                #region Lieferschein

                if (CoreFunctionNumber == FC.Lieferschein) {
                    string sheetVorlage = Settings.Default.VorlageExcelLieferschein;
                    string sAfter = Core.GetAfterSheetName(exApp, mySheet.ProjektNummer, Core.SheetType.Lieferschein, wb, log);
                    string newSheetName = Core.GetSheetName(Core.SheetType.Lieferschein, mySheet.ProjektNummer, wb, sh);
                    Worksheet afterSheet = wb.Sheets[sAfter];
                    Worksheet ls = wb.Sheets.Add(After: afterSheet, Type: sheetVorlage);
                    ls.Name = newSheetName;
                    log.Abort = false;
                    Core.LieferscheinNeu(wb, sh, ls, log);
                    if (log.Abort) {
                        ((Worksheet)wb.Sheets[ls.Name]).Delete();
                        return;
                    }
                    ls.CustomProperties.Add("SheetType", Core.SheetType.Lieferschein);
                    ls.Activate();

                }

                #endregion

                #region Projektbericht

                if (CoreFunctionNumber == FC.Projektbericht) {
                    ProjectSheet sheet = new ProjectSheet(sh);
                    string sAfter = Core.GetAfterSheetName(exApp, mySheet.ProjektNummer, Core.SheetType.Projektbericht, wb, log);
                    string newSheetName = Core.GetSheetName(Core.SheetType.Projektbericht, mySheet.ProjektNummer, wb, sh);

                    Worksheet afterSheet = wb.Sheets[sAfter];
                    Worksheet pb = wb.Sheets.Add(After: afterSheet, Type: Settings.Default.VorlageExcelProjektBericht);
                    pb.Name = newSheetName;
                    log.Abort = false;
                    Core.ProjektBerichtNeu(exApp, wb, sh, pb, log);
                    if (log.Abort) {
                        ((Worksheet)wb.Sheets[newSheetName]).Delete();
                        return;
                    }
                    pb.CustomProperties.Add("SheetType", Core.SheetType.Projektbericht);
                    pb.Activate();

                }

                #endregion

                #region Projekt Neu

                if (CoreFunctionNumber == FC.Projekt) {
                    Core.ProjektNeu(exApp, wb, sh, log);
                }

                #endregion

                #region Rechnung

                if (CoreFunctionNumber == FC.Rechnug) {
                    ProjectSheet sheet = new ProjectSheet(sh);
                    string sAfter = Core.GetAfterSheetName(exApp, mySheet.ProjektNummer, Core.SheetType.Rechnung, wb, log);
                    string newSheetName = Core.GetSheetName(Core.SheetType.Rechnung, mySheet.ProjektNummer, wb, sh);

                    Worksheet afterSheet = wb.Sheets[sAfter];
                    Worksheet rechnung = wb.Sheets.Add(After: afterSheet, Type: Settings.Default.VorlageExcelAngebot);
                    rechnung.Name = newSheetName;
                    Core.RechnungNeu(exApp, wb, sh, rechnung, log);
                    rechnung.CustomProperties.Add("SheetType", Core.SheetType.Rechnung);
                    rechnung.Activate();
                }

                #endregion

                #endregion

                #region Export + Funktion

                #region Export Aepü

                if (CoreFunctionNumber == FC.Aepü) {
                    Core.ExportAepü(exApp, wb, sh, log);
                }

                #endregion

                #region Export Leistungen Projekt

                if (CoreFunctionNumber == FC.LeistungenProjekt) {
                    string wbName = wb.Name;
                    Core.ExportJobevidenz(exApp, wb, sh, log);
                    exApp.Windows[wbName].Activate();
                    wb = exApp.ActiveWorkbook;
                    Core.ExportLeistungen(exApp, wb, sh, log);
                }

                #endregion

                #region Export Leistungen

                if (CoreFunctionNumber == FC.Leistungen) {
                    Core.ExportLeistungen(exApp, wb, sh, log);
                }

                #endregion

                #endregion

                #region Export + Funktion + Dokument

                #region Dokument Angebot

                if (CoreFunctionNumber == FC.DokumentAngebot) {
                    Core.DokumentAngebot(exApp, wb, sh, log);
                }

                #endregion

                #region Dokument Rechnung

                if(CoreFunctionNumber == FC.DokumentRechnung) {
                    Core.DokumentRechnung(exApp, wb, sh, log);
                }

                #endregion

                #endregion

                #region RechteMaus Menü

                if (CoreFunctionNumber == FC.SetRightMouseMenu) {
                    Core.SetKontextMenu(exApp, wb, sh, log);
                }

                #endregion

                #endregion

                #region Workbook Events

                #region WB Activate

                if (CoreFunctionNumber == FC.WBActivate) {
                    Core.WBActivate(exApp, wb, sh, log);
                }

                #endregion

                #region WB AfterSave

                if (CoreFunctionNumber == FC.WBAfterSave) {
                    Core.WBAfterSave(exApp, wb, sh);
                }

                #endregion

                #region WB Deactivate

                if (CoreFunctionNumber == FC.WBDeactivate) {
                    Core.WBDeactivate(exApp, wb, sh);
                }

                #endregion

                #region WB SheetActivate

                if (CoreFunctionNumber == FC.WBSheetActivate) {
                    Core.WbSheetActivate(exApp, wb, sh);
                }

                #endregion

                #region WB SheetDeactivate

                if (CoreFunctionNumber == FC.WBSheetDeactivate) {
                    //Core.WbSheetActivate(exApp, wb, sh);
                }

                #endregion

                #endregion

                #region Worksheet Events
                #endregion

                #region Diverses

                if (CoreFunctionNumber == FC.TestRoutine) {
                    Core.TestRoutine(exApp, wb, sh);
                }

                #endregion

            } catch (Exception ex) {
                log.Add("ExcelCore: ", ex);
            } finally {
                //if (log.HasErrors) {
                //    log.SaveToDisk();
                //}
                log.SaveToDisk();
                SetApplication(exApp, true);
            }
        }

        public void WordWorker(myWord.Application appWord, myWord.Document mDoc, int CoreFunctionNumber) {
            Logger log = new Logger();

            #region SendThisDocument

            if (CoreFunctionNumber == FC.wordSendThisDocument) {
                WordCore.SendThisDocument(appWord, mDoc, log);
            }

            #endregion
        }

        #endregion

        #region Functions

        public bool fnExcelCoreBool(Microsoft.Office.Interop.Excel.Application exApp, Workbook wb, Worksheet sh, int CoreFunctionNumber, bool cancel) {

            #region ExcelSettings

            SetApplication(exApp, false);

            #endregion

            try {

                #region Workbook Events

                #region WB Activate

                if (CoreFunctionNumber == FC.WBActivate) {
                    cancel = false;
                    Core.WBActivate(exApp, wb, sh, log);
                }

                #endregion

                #region WB AfterSave

                if (CoreFunctionNumber == FC.WBAfterSave) {
                    Core.WBAfterSave(exApp, wb, sh);
                }

                #endregion

                #region WB BeforeClose

                if (CoreFunctionNumber == FC.WBBeforeClose) {
                    cancel = Core.WbBeforeClose(exApp, wb, sh, cancel);
                }

                #endregion

                #region WB BeforeSave

                if (CoreFunctionNumber == FC.WBBeforeSave) {
                    Core.WBBeforeSave(exApp, wb, sh, cancel);
                }

                #endregion

                #region WB Deactivate

                if (CoreFunctionNumber == FC.WBDeactivate) {
                    Core.WBDeactivate(exApp, wb, sh);
                }

                #endregion

                #region WB Open

                if (CoreFunctionNumber == FC.WBOpen) {
                    log.Add("WB Open");
                    Core.WbOpen(exApp, wb, sh, log);
                }

                #endregion

                #region WB SheetActivate

                if (CoreFunctionNumber == FC.WBSheetActivate) {
                    Core.WbSheetActivate(exApp, wb, sh);
                }

                #endregion

                #region WB SheetCalculate

                if (CoreFunctionNumber == FC.WBSheetCalculate) {
                    Core.WbSheetCalculate(exApp, wb, sh);
                }

                #endregion

                #region WB SheetChange

                if (CoreFunctionNumber == FC.WBSheetChange) {
                    Core.WbSheetChange(exApp, wb, sh);
                }

                #endregion

                #region WB SheetDeactivate

                if (CoreFunctionNumber == FC.WBSheetDeactivate) {
                    Core.WbSheetDeactivate(exApp, wb, sh);
                }

                #endregion

                #endregion

                #region Worksheet Events

                if (CoreFunctionNumber == FC.WSChange) {
                    Core.WSChange(exApp, wb, sh, log);
                }

                #endregion

            } catch (Exception ex) {
                log.Add("fnExcelCoreBool:" + wb.Name, ex);
            } finally {
                if (log.HasErrors) {
                    log.SaveToDisk();
                }
                SetApplication(exApp, true);
            }
            return cancel;
        }

        public bool fnExcelCoreTarget(Microsoft.Office.Interop.Excel.Application exApp, Workbook wb, Worksheet sh, Range target, int CoreFunctionNumber, bool cancel) {
            try {
                cancel = Core.WSChange(exApp, wb, sh, target, cancel, log);
            } catch (Exception ex) {
                log.Add("fnExcelCoreTarget", ex);
            } finally {
                if (log.HasErrors) {
                    log.SaveToDisk();
                }
            }
            return cancel;
        }

        #endregion

        #region Destructor

        ~ExcelWork() {
            log.Add("End ExcelWork");
            if (log.LogListCount > 2) {
                log.SaveToDisk();
            }
        }

        #endregion

    }
}
